package common

import (
	"MyBlogv2/common/helper"
	"context"
	"io"
	"log"
	"os"
	"path"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
)

var minioClient *minio.Client = InitMinioClient()

var MinIOSever = "47.100.111.28:9000"
var BUCKET_NAME = "myblogv2"
var MinIOKey = "YTPxk6Qs8yIMUtjm"
var MinIOSecret = "JKwk8bpyDTrojrD1oUBCtmg35qNOAPhy"
var Prefix = "http://" + MinIOSever + "/" + BUCKET_NAME + "/"

func InitMinioClient() *minio.Client {
	client, err := minio.New(MinIOSever, &minio.Options{
		Creds: credentials.NewStaticV4(MinIOKey, MinIOSecret, ""),
	})
	if err != nil {
		log.Fatalf("Error creating MinIO client: %v", err)
	}
	ok, err := client.BucketExists(context.Background(), "xcxcpanimage")
	if err != nil {
		log.Fatalf("Error creating MinIO client: %v", err)
	}
	if ok {
		log.Println("MinIO Init Success")
	}
	return client
}

func CheckAvatarExists(fileName string) bool {
	_, err := minioClient.StatObject(context.Background(), BUCKET_NAME, fileName, minio.StatObjectOptions{})
	return err == nil
}

func DownloadImage(fileName string) (file *os.File, err error) {
	object, err := minioClient.GetObject(context.Background(), BUCKET_NAME, fileName, minio.GetObjectOptions{})
	if err != nil {
		return nil, err
	}
	tempFile, err := os.CreateTemp("", "downloaded-image-*.jpg")
	if err != nil {
		return nil, err
	}
	_, err = io.Copy(tempFile, object)
	if err != nil {
		os.Remove(tempFile.Name())
		tempFile.Close()
		return nil, err
	}
	_, err = tempFile.Seek(0, 0)
	if err != nil {
		os.Remove(tempFile.Name())
		tempFile.Close()
		return nil, err
	}
	return tempFile, nil
}

func GenerateFileName() string {
	return helper.GetUUID()
}

func UploadImage(fileName string, file *os.File) (finalUrl string, err error) {
	newFileName := GenerateFileName()
	exists := CheckAvatarExists(newFileName + ".jpg")
	if exists {
		DelImage(newFileName + ".jpg")
	}

	ext := path.Ext(fileName)
	if ext != ".jpg" && ext != ".png" && ext != ".jpeg" {
		return "", err
	}
	fileInfo, err := file.Stat()
	if err != nil {
		return "", err
	}
	objectName := newFileName + ".jpg"
	contentType := "image/jpg"
	uploadInfo, err := minioClient.PutObject(context.Background(), BUCKET_NAME, objectName, file, fileInfo.Size(),
		minio.PutObjectOptions{ContentType: contentType})
	if err != nil {
		return "", err
	}
	log.Printf("Successfully uploaded %s of size %d\n", objectName, uploadInfo.Size)
	return Prefix + objectName, nil
}

func DelImage(fileName string) error {
	err := minioClient.RemoveObject(context.Background(), BUCKET_NAME, fileName, minio.RemoveObjectOptions{})
	if err != nil {
		log.Fatalln(err)
		return err
	}
	return nil
}

func UploadFile(objectName string, fileReader io.Reader, fileSize int64, contentType string) (string, error) {
	// 检查存储桶是否存在
	exists, err := minioClient.BucketExists(context.Background(), BUCKET_NAME)
	if err != nil {
		return "", err
	}
	if !exists {
		// 如果存储桶不存在，创建它
		err = minioClient.MakeBucket(context.Background(), BUCKET_NAME, minio.MakeBucketOptions{})
		if err != nil {
			return "", err
		}
	}

	// 上传文件到 MinIO
	uploadInfo, err := minioClient.PutObject(context.Background(), BUCKET_NAME, objectName, fileReader, fileSize,
		minio.PutObjectOptions{ContentType: contentType})
	if err != nil {
		return "", err
	}

	// 文件上传成功后，记录日志
	log.Printf("File uploaded successfully to %s/%s, size: %d bytes", BUCKET_NAME, objectName, uploadInfo.Size)

	// 返回文件的访问URL
	fileUrl := Prefix + objectName
	return fileUrl, nil
}

// UploadSVGFile 上传SVG文件到MinIO
func UploadSVGFile(filePath string, objectName string) (string, error) {
	// 打开文件
	file, err := os.Open(filePath)
	if err != nil {
		return "", err
	}
	defer file.Close()

	// 获取文件信息
	fileInfo, err := file.Stat()
	if err != nil {
		return "", err
	}

	// 检查存储桶是否存在
	exists, err := minioClient.BucketExists(context.Background(), BUCKET_NAME)
	if err != nil {
		return "", err
	}
	if !exists {
		// 如果存储桶不存在，创建它
		err = minioClient.MakeBucket(context.Background(), BUCKET_NAME, minio.MakeBucketOptions{})
		if err != nil {
			return "", err
		}
	}

	// 上传SVG文件到MinIO
	uploadInfo, err := minioClient.PutObject(context.Background(), BUCKET_NAME, objectName, file, fileInfo.Size(),
		minio.PutObjectOptions{ContentType: "image/svg+xml"})
	if err != nil {
		return "", err
	}

	// 文件上传成功后，记录日志
	log.Printf("SVG file uploaded successfully to %s/%s, size: %d bytes", BUCKET_NAME, objectName, uploadInfo.Size)

	// 返回文件的访问URL
	fileUrl := Prefix + objectName
	return fileUrl, nil
}
